use crate::{click_set::ClickSet, state::State};
use derive_more::Deref;

#[derive(Debug, Deref, Eq)]
pub struct Strategy {
    /// 分数，但不一定
    ///
    /// 本结构没有存储[`State`]，因此无法知道是从哪个状态来的。
    /// 若分数参与比较，不能分辨在不同状态上得到同一分数的同一策略。
    /// 于是，我直接让分数不参与比较，并且可以由外部随意更改。
    ///
    /// 因此，[`Strategy`]的分数和状态，应由所有者保证其意义。
    /// 如果从别处获取到一个，不能保证其分数之类的意义。
    pub score: usize,
    #[deref]
    click_set: ClickSet,
}

impl Strategy {
    pub fn new(click_set: ClickSet, state: &mut State) -> Self {
        let score = click_set.run(state);
        Self { score, click_set }
    }
}

/// 分数是不固定的，与相等性无关
impl PartialEq for Strategy {
    fn eq(&self, other: &Self) -> bool {
        **self == **other
    }
}

/// 分数是不固定的，与相等性无关；
/// [`Layout`]应该大都相等，就不哈希了。
///
/// [`Layout`]: crate::board::Layout
impl std::hash::Hash for Strategy {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.clicks().hash(state);
    }
}
